﻿using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace EcoSystem
{
    public class EnumSchemaFilter : ISchemaFilter
    {
        /// <summary>
        /// 枚举列表项标题说明
        /// </summary>
        public static string Prefix { get; set; } = "<p>枚举项说明:</p>";

        /// <summary>
        ///枚举项格式化显示说明, 0 : value, 1: Name, 2: Description
        /// </summary>
        public static string Format { get; set; } = "<b>{0} - {1}</b>:{2}";

        /// <summary>
        /// Apply this schema filter.
        /// </summary>
        /// <param name="schema">Target schema object.</param>
        /// <param name="context">Schema filter context.</param>
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            var type = context.Type;

            // Only process enums and...
            if (!type.IsEnum)
            {
                return;
            }

            var sb = new StringBuilder(schema.Description);

            if (!string.IsNullOrEmpty(Prefix))
            {
                sb.AppendLine(Prefix);
            }

            sb.AppendLine("<ul>");

            var dict = GetEnumDicctionarys(type);
            foreach (var item in Enum.GetValues(type))
            {
                var value = Convert.ToInt64(item);
                var name = item.ToString();
                var description = dict.ContainsKey(name) ? dict[name] : "无描述";
                sb.AppendLine(string.Format("<li>" + Format + "</li>", value, name, description));
            }
            sb.AppendLine("</ul>");
            schema.Description = sb.ToString();
        }


        ///<summary>
        /// 返回 Dic&lt;枚举项，描述&gt;
        ///</summary>
        ///<param name="enumType">枚举的类型</param>
        ///<returns>Dic&lt;枚举项，描述&gt;</returns>
        static Dictionary<string, string> GetEnumDicctionarys(Type enumType)
        {
            Dictionary<string, string> dic = new();
            FieldInfo[] fieldinfos = enumType.GetFields();
            foreach (FieldInfo field in fieldinfos)
            {
                if (field.FieldType.IsEnum)
                {
                    Object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (objs.Length > 0)
                    {
                        dic.Add(field.Name, ((DescriptionAttribute)objs[0]).Description);
                    }
                }

            }
            return dic;
        }

    }
}
